<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Patching HTML</title>
		<style>
			.items {
				margin: 1em 0;
				padding: 0;
				display: flex;
				flex-wrap: wrap;
				gap: 2px;
			}

			.items > * {
				display: flex;
				align-items: center;
				justify-content: center;
				width: 3em;
				height: 2em;
				margin: 0;
				padding: 0;
				background: #eee;
			}
		</style>
	</head>
	<body>
		<div id="app"></div>
		<script type="module">
			import { measureName, measureMemory } from './util.js';
			import { createRoot, createElement as h, Component } from 'framework';

			function Row(props) {
				return h('article', null, props.children);
			}

			function App(props) {
				return h('div', {}, [
					h(
						'div',
						{ class: 'items' },
						props.items.map(id => h(Row, { key: id }, id))
					)
				]);
			}

			const count = 1000;
			const start = 20;
			const end = 600;

			const newItems = () =>
				Array(count)
					.fill(0)
					.map((item, i) => i);
			let items = newItems();
			let currentItems = items;

			const root = createRoot(document.getElementById('app'));
			root.render(h(App, { items }));

			function runPatch() {
				items = newItems().filter(id => {
					const isVisible = currentItems.includes(id);
					return id >= start && id <= end ? !isVisible : isVisible;
				});
				currentItems = items;

				root.render(h(App, { items }));
			}

			async function warmup() {
				const count = 25;

				for (let i = 0; i < count; i++) {
					runPatch();
					await new Promise(r => requestAnimationFrame(r));
				}
			}

			warmup().then(async () => {
				performance.mark('start');
				runPatch();
				await new Promise(r => requestAnimationFrame(r));
				performance.mark('stop');
				performance.measure(measureName, 'start', 'stop');

				measureMemory();
			});
		</script>
	</body>
</html>
